package com.sojson.util.security.shiro.interceptor.core;

import java.util.Collection;

import org.apache.shiro.aop.MethodInvocation;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.aop.AuthorizingAnnotationMethodInterceptor;
import org.apache.shiro.authz.aop.AuthorizingMethodInterceptor;
import org.apache.shiro.authz.aop.PermissionAnnotationMethodInterceptor;
import org.apache.shiro.authz.aop.RoleAnnotationMethodInterceptor;

/**
 * 重写这个抽象类是因为原来的类的构造方法默认添加了几个过滤器,那几个过滤器返回的异常信息不太好理解,所以为了去掉那几个过滤器就重写了这个类
 * 重写之前的抽象类为:org.apache.shiro.authz.aop.AnnotationsAuthorizingMethodInterceptor
 * 
 * @author liu
 * @Date 2020-06-12 09:34:59
 * @Description
 *
 */
public abstract class CustomAnnotationsAuthorizingMethodInterceptor extends AuthorizingMethodInterceptor {

    /**
     * The method interceptors to execute for the annotated method.
     */
    protected Collection<AuthorizingAnnotationMethodInterceptor> methodInterceptors;

    /**
     * Default no-argument constructor that defaults the {@link #methodInterceptors
     * methodInterceptors} attribute to contain two interceptors by default - the
     * {@link RoleAnnotationMethodInterceptor RoleAnnotationMethodInterceptor} and
     * the {@link PermissionAnnotationMethodInterceptor
     * PermissionAnnotationMethodInterceptor} to support role and permission
     * annotations.
     */
    public CustomAnnotationsAuthorizingMethodInterceptor() {
//        // shiro默认添加的拦截器
//        methodInterceptors = new ArrayList<AuthorizingAnnotationMethodInterceptor>(5);
//        methodInterceptors.add(new RoleAnnotationMethodInterceptor());
//        methodInterceptors.add(new PermissionAnnotationMethodInterceptor());
//        methodInterceptors.add(new AuthenticatedAnnotationMethodInterceptor());
//        methodInterceptors.add(new UserAnnotationMethodInterceptor());
//        methodInterceptors.add(new GuestAnnotationMethodInterceptor());
    }

    /**
     * Returns the method interceptors to execute for the annotated method.
     * <p/>
     * Unless overridden by the {@link #setMethodInterceptors(java.util.Collection)}
     * method, the default collection contains a
     * {@link RoleAnnotationMethodInterceptor RoleAnnotationMethodInterceptor} and a
     * {@link PermissionAnnotationMethodInterceptor
     * PermissionAnnotationMethodInterceptor} to support role and permission
     * annotations automatically.
     * 
     * @return the method interceptors to execute for the annotated method.
     */
    public Collection<AuthorizingAnnotationMethodInterceptor> getMethodInterceptors() {
        return methodInterceptors;
    }

    /**
     * Sets the method interceptors to execute for the annotated method.
     * 
     * @param methodInterceptors the method interceptors to execute for the
     * annotated method.
     * @see #getMethodInterceptors()
     */
    public void setMethodInterceptors(Collection<AuthorizingAnnotationMethodInterceptor> methodInterceptors) {
        this.methodInterceptors = methodInterceptors;
    }

    /**
     * Iterates over the internal {@link #getMethodInterceptors()
     * methodInterceptors} collection, and for each one, ensures that if the
     * interceptor
     * {@link AuthorizingAnnotationMethodInterceptor#supports(org.apache.shiro.aop.MethodInvocation)
     * supports} the invocation, that the interceptor
     * {@link AuthorizingAnnotationMethodInterceptor#assertAuthorized(org.apache.shiro.aop.MethodInvocation)
     * asserts} that the invocation is authorized to proceed.
     */
    @Override
    protected void assertAuthorized(MethodInvocation methodInvocation) throws AuthorizationException {
        // default implementation just ensures no deny votes are cast:
        Collection<AuthorizingAnnotationMethodInterceptor> aamis = getMethodInterceptors();
        if (aamis != null && !aamis.isEmpty()) {
            for (AuthorizingAnnotationMethodInterceptor aami : aamis) {
                if (aami.supports(methodInvocation)) {
                    aami.assertAuthorized(methodInvocation);
                }
            }
        }
    }
}
